home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / fragrouter / Libnet-0.99b / src / if_addr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-26  |  6.9 KB  |  259 lines

  1. /*
  2.  *  $Id: if_addr.c,v 1.2 1999/05/27 02:32:19 dugsong Exp $
  3.  *
  4.  *  libnet
  5.  *  if_addr.c - interface selection code
  6.  *
  7.  *  Copyright (c) 1998, 1999 Mike D. Schiffman <mike@infonexus.com>
  8.  *                           route|daemon9 <route@infonexus.com>
  9.  *  Originally pulled from traceroute sources.
  10.  *  All rights reserved.
  11.  *
  12.  * Redistribution and use in source and binary forms, with or without
  13.  * modification, are permitted provided that the following conditions
  14.  * are met:
  15.  * 1. Redistributions of source code must retain the above copyright
  16.  *    notice, this list of conditions and the following disclaimer.
  17.  * 2. Redistributions in binary form must reproduce the above copyright
  18.  *    notice, this list of conditions and the following disclaimer in the
  19.  *    documentation and/or other materials provided with the distribution.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  */
  34.  
  35. #if (HAVE_CONFIG_H)
  36. #include "../include/config.h"
  37. #endif
  38. #include "../include/libnet.h"
  39. #ifdef HAVE_SYS_SOCKIO_H
  40. #include <sys/sockio.h>
  41. #endif
  42.  
  43. #define MAX_IPADDR 32
  44.  
  45. /*
  46.  *  Return the interface list
  47.  */
  48. int
  49. ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, register char *errbuf)
  50. {
  51.     register int fd, nipaddr;
  52. #ifdef HAVE_SOCKADDR_SA_LEN
  53.     register int n;
  54. #endif
  55.     register struct ifreq *ifrp, *ifend, *ifnext, *mp;
  56.     register struct sockaddr_in *sin;
  57.     register struct libnet_ifaddr_list *al;
  58.     struct ifconf ifc;
  59.     struct ifreq ibuf[MAX_IPADDR], ifr;
  60.     char device[sizeof(ifr.ifr_name) + 1];
  61.     static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR];
  62.  
  63.     fd = socket(AF_INET, SOCK_DGRAM, 0);
  64.     if (fd < 0)
  65.     {
  66.         sprintf(errbuf, "socket: %s", strerror(errno));
  67.         return (-1);
  68.     }
  69.     ifc.ifc_len = sizeof(ibuf);
  70.     ifc.ifc_buf = (caddr_t)ibuf;
  71.  
  72.     if (ioctl(fd,
  73.             SIOCGIFCONF,
  74.             (char *)&ifc) < 0 || ifc.ifc_len < sizeof(struct ifreq))
  75.     {
  76.         sprintf(errbuf, "SIOCGIFCONF: %s", strerror(errno));
  77.         close(fd);
  78.         return (-1);
  79.     }
  80.     ifrp = ibuf;
  81.     ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);
  82.  
  83.     al = ifaddrlist;
  84.     mp = NULL;
  85.     nipaddr = 0;
  86.     for (; ifrp < ifend; ifrp = ifnext)
  87.     {
  88. #ifdef HAVE_SOCKADDR_SA_LEN
  89.         n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
  90.         if (n < sizeof(*ifrp))
  91.         {
  92.             ifnext = ifrp + 1;
  93.         }
  94.         else
  95.         {
  96.             ifnext = (struct ifreq *)((char *)ifrp + n);
  97.         }
  98.         if (ifrp->ifr_addr.sa_family != AF_INET) continue;
  99. #else
  100.         ifnext = ifrp + 1;
  101. #endif
  102.         /*
  103.          * Need a template to preserve address info that is
  104.          * used below to locate the next entry.  (Otherwise,
  105.          * SIOCGIFFLAGS stomps over it because the requests
  106.          * are returned in a union.)
  107.          */
  108.         strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
  109.         if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0)
  110.         {
  111.             if (errno == ENXIO) continue;
  112.             sprintf(errbuf,
  113.                     "SIOCGIFFLAGS: %.*s: %s",
  114.                     (int)sizeof(ifr.ifr_name),
  115.                      ifr.ifr_name,
  116.                      strerror(errno));
  117.             close(fd);
  118.             return (-1);
  119.         }
  120.  
  121.         /* Must be up and not the loopback */
  122.         if ((ifr.ifr_flags & IFF_UP) == 0 || ISLOOPBACK(&ifr)) continue;
  123.         
  124.         strncpy(device, ifr.ifr_name, sizeof(ifr.ifr_name));
  125.         device[sizeof(device) - 1] = '\0';
  126.         if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0)
  127.         {
  128.             sprintf(errbuf, "SIOCGIFADDR: %s: %s", device, strerror(errno));
  129.             close(fd);
  130.             return (-1);
  131.         }
  132.     
  133.         sin = (struct sockaddr_in *)&ifr.ifr_addr;
  134.         al->addr = sin->sin_addr.s_addr;
  135.         /*
  136.          *  Replaced savestr() with strdup().  -- MDS
  137.          */
  138.         al->device = strdup(device);
  139.         ++al;
  140.         ++nipaddr;
  141.     }
  142.     close(fd);
  143.  
  144.     *ipaddrp = ifaddrlist;
  145.     return (nipaddr);
  146. }
  147.  
  148. int
  149. libnet_select_device(struct sockaddr_in *sin, u_char **device, u_char *errbuf)
  150. {
  151.     int c, i;
  152.     char err_buf[132];
  153.     struct libnet_ifaddr_list *address_list;
  154.  
  155. #if (__solaris__)
  156.    /* 
  157.     *  XXX - this is temporary and needs to be better documented.
  158.     */
  159.     *device = "le0";     
  160.     return (1);
  161. #else
  162.     /*
  163.      *  Number of interfaces.
  164.      */
  165.     c = ifaddrlist(&address_list, err_buf);
  166.     if (c < 0)
  167.     {
  168.         sprintf(errbuf, "ifaddrlist : %s\n", err_buf);
  169.         return (-1);
  170.     }
  171.     else if (c == 0)
  172.     {
  173.         sprintf(errbuf, "No network interfaces found.\n");
  174.         return (-1);
  175.     }
  176.     if (*device)
  177.     {
  178.         for (i = c; i; --i, ++address_list)
  179.         {
  180.             if (!(strcmp(*device, address_list->device)))
  181.             {
  182.                 break;
  183.             }
  184.         }
  185.         if (i <= 0)
  186.         {
  187.             sprintf(errbuf, "Can't find interface %s\n", *device);
  188.             return (-1);
  189.         }
  190.     }
  191.     sin->sin_family = AF_INET;
  192.     sin->sin_addr.s_addr = address_list->addr;
  193.  
  194.     /*
  195.      *  Do we need to assign a name to device?
  196.      */
  197.     if (!*device)
  198.     {
  199.         if (c > 1)
  200.     {
  201. #if (__DEBUG)
  202.             fprintf(stdout,
  203.                 "Multiple interfaces found, using %s @ %s.\n",
  204.                 host_lookup(sin->sin_addr.s_addr, 0),
  205.                 address_list->device);
  206. #endif
  207.         }
  208.         *device = address_list->device;
  209.         return (1);
  210.     }
  211.     return (-1);
  212. }
  213. #endif  /* __solaris__ */
  214.  
  215. #if RAW_IS_COOKED
  216. int
  217. libnet_select_device_by_ip(u_char **device, u_long ip, u_char *errbuf)
  218. {
  219.     int c, i;
  220.     char err_buf[132];
  221.     struct libnet_ifaddr_list *address_list;
  222.  
  223.     /*
  224.      *  Number of interfaces.
  225.      */
  226.     c = ifaddrlist(&address_list, err_buf);
  227.  
  228.     if (c < 0)
  229.     {
  230.         sprintf(errbuf, "ifaddrlist : %s\n", err_buf);
  231.         return (-1);
  232.     }
  233.     else if (c == 0)
  234.     {
  235.         sprintf(errbuf, "No network interfaces found.\n");
  236.         return (-1);
  237.     }
  238.  
  239.     for (i = c; i; --i, ++address_list)
  240.     {
  241.         if (ip==address_list->addr)
  242.         {
  243.             break;
  244.         }
  245.     }
  246.  
  247.     if (i <= 0)
  248.     {
  249.         sprintf(errbuf, "Can't find interface that matches %s.\n", 
  250.                 host_lookup(ip,0));
  251.         return (-1);
  252.     }
  253.  
  254.     *device = address_list->device;
  255.     return (1);
  256. }
  257. #endif /* RAW_IS_COOKED */
  258. /* EOF */
  259.